//
//  MovEncodeToMpegTool.m
//  XLConversationInputView
//
//  Created by ilongge on 2022/8/5.
//

#import <Photos/Photos.h>
#import <AVFoundation/AVFoundation.h>
#import "XLMovEncodeToMpegTool.h"

@implementation XLMovEncodeToMpegTool

/// 转码 MOV--MP4
/// @param resourceAsset MOV资源
/// @param exportQuality 预设
/// @param resultBlock 转码后的MP4文件链接
+ (void)convertMovToMp4FromPHAsset:(PHAsset*)resourceAsset
     andAVAssetExportPresetQuality:(NSString *)exportQuality
                    andResultBlock:(MovEncodeResultBlock)resultBlock {
    NSDictionary *videoInfo = [self getVideoInfo:resourceAsset];
    NSLog(@"\n%@", videoInfo);
    
    PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
    options.version = PHVideoRequestOptionsVersionCurrent;
    options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
    options.networkAccessAllowed = true;
    
    PHImageManager *manager = [PHImageManager defaultManager];
    [manager requestAVAssetForVideo:resourceAsset
                            options:options
                      resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
        
        if ([asset isKindOfClass:[AVURLAsset class]]) {
            AVURLAsset *urlAsset = (AVURLAsset *)asset;
            [XLMovEncodeToMpegTool convertMovToMp4FromAVURLAsset:urlAsset
                                   andAVAssetExportPresetQuality:exportQuality
                                                  andResultBlock:resultBlock];
        }
        else{
            NSError *error = [NSError errorWithDomain:@"ConvertMovToMp4ErrorDomain"
                                                 code:10008
                                             userInfo:@{NSLocalizedDescriptionKey:@"resource type error"}];
            [self movEncodeToMpegToolResult:nil error:error andResultBlock:resultBlock];
        }
        
    }];
}

+ (void)movEncodeToMpegToolResult:(NSURL *)url
                            error:(NSError *)error
                   andResultBlock:(MovEncodeResultBlock)resultBlock {
    if (resultBlock) {
        resultBlock(url, error);
    }
}

+ (NSString *)choseAVURLAsset:(AVURLAsset*)avAsset exportPresetQualityFor:(NSString *)exportQuality
{
    NSString *matchPreset = nil;
    NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
    if ([compatiblePresets containsObject:exportQuality]){
        matchPreset = exportQuality;
    }
    else{
        if ([compatiblePresets containsObject:AVAssetExportPresetHEVC1920x1080]){
            matchPreset = AVAssetExportPresetHEVC1920x1080;
        }
        else if ([compatiblePresets containsObject:AVAssetExportPreset1920x1080]){
            matchPreset = AVAssetExportPreset1920x1080;
        }
        else if ([compatiblePresets containsObject:AVAssetExportPresetMediumQuality]){
            matchPreset = AVAssetExportPresetMediumQuality;
        }
        else if ([compatiblePresets containsObject:AVAssetExportPreset1280x720]){
            matchPreset = AVAssetExportPreset1280x720;
        }
        else if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality]){
            matchPreset = AVAssetExportPresetLowQuality;
        }
        else if ([compatiblePresets containsObject:AVAssetExportPreset960x540]){
            matchPreset = AVAssetExportPreset960x540;
        }
        else if ([compatiblePresets containsObject:AVAssetExportPreset640x480]){
            matchPreset = AVAssetExportPreset640x480;
        }
    }
    return matchPreset;
}



#pragma mark ### MOV转码MP4
+ (void)convertMovToMp4FromAVURLAsset:(AVURLAsset*)urlAsset
        andAVAssetExportPresetQuality:(NSString *)exportQuality
                       andResultBlock:(MovEncodeResultBlock)resultBlock {
    AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:urlAsset.URL options:nil];
    exportQuality = [XLMovEncodeToMpegTool choseAVURLAsset:avAsset exportPresetQualityFor:exportQuality];
    // 预设
    if (exportQuality) {
        //  在Documents目录下创建一个名为FileData的文件夹
        NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"Cache/VideoData"];
        
        NSFileManager *fileManager = [NSFileManager defaultManager];
        BOOL isDir = FALSE;
        BOOL isDirExist = [fileManager fileExistsAtPath:path isDirectory:&isDir];
        if(!(isDirExist && isDir)) {
            BOOL bCreateDir = [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
            if(!bCreateDir){
                NSLog(@"创建文件夹失败！%@",path);
            }
            NSLog(@"创建文件夹成功，文件路径%@",path);
        }
        
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];
        [formatter setDateFormat:@"yyyyMMddHHmmss"]; //每次启动后都保存一个新的文件中
        NSString *dateStr = [formatter stringFromDate:[NSDate date]];
        
        NSString *resultPath = [path stringByAppendingFormat:@"/%@.mp4",dateStr];
        NSLog(@"resultFileName = %@",dateStr);
        
        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:avAsset
                                                                               presetName:exportQuality];
        exportSession.outputURL = [NSURL fileURLWithPath:resultPath];
        exportSession.outputFileType = AVFileTypeMPEG4;
        exportSession.shouldOptimizeForNetworkUse = YES;
        
        [exportSession exportAsynchronouslyWithCompletionHandler:^(void) {
            switch (exportSession.status) {
                case AVAssetExportSessionStatusUnknown: {
                    NSError *error = [NSError errorWithDomain:@"ConvertMovToMp4ErrorDomain"
                                                         code:10001
                                                     userInfo:@{NSLocalizedDescriptionKey:@"AVAssetExportSessionStatusUnknown"}];
                    [self movEncodeToMpegToolResult:nil error:error andResultBlock:resultBlock];
                }
                    break;
                case AVAssetExportSessionStatusWaiting: {
                    NSError *error = [NSError errorWithDomain:@"ConvertMovToMp4ErrorDomain"
                                                         code:10002
                                                     userInfo:@{NSLocalizedDescriptionKey:@"AVAssetExportSessionStatusWaiting"}];
                    [self movEncodeToMpegToolResult:nil error:error andResultBlock:resultBlock];
                }
                    break;
                case AVAssetExportSessionStatusExporting: {
                    NSError *error = [NSError errorWithDomain:@"ConvertMovToMp4ErrorDomain"
                                                         code:10003
                                                     userInfo:@{NSLocalizedDescriptionKey:@"AVAssetExportSessionStatusExporting"}];
                    [self movEncodeToMpegToolResult:nil error:error andResultBlock:resultBlock];
                }
                    break;
                case AVAssetExportSessionStatusCompleted: {
                    [self movEncodeToMpegToolResult:exportSession.outputURL error:nil andResultBlock:resultBlock];
                }
                    break;
                case AVAssetExportSessionStatusFailed: {
                    NSError *error = [NSError errorWithDomain:@"ConvertMovToMp4ErrorDomain"
                                                         code:10005
                                                     userInfo:@{NSLocalizedDescriptionKey:@"AVAssetExportSessionStatusFailed"}];
                    [self movEncodeToMpegToolResult:nil error:error andResultBlock:resultBlock];
                }
                    break;
                case AVAssetExportSessionStatusCancelled: {
                    NSError *error = [NSError errorWithDomain:@"ConvertMovToMp4ErrorDomain"
                                                         code:10006
                                                     userInfo:@{NSLocalizedDescriptionKey:@"AVAssetExportSessionStatusCancelled"}];
                    [self movEncodeToMpegToolResult:nil error:error andResultBlock:resultBlock];
                }
                    break;
            }
        }];
    }
    else{
        NSError *error = [NSError errorWithDomain:@"ConvertMovToMp4ErrorDomain"
                                             code:10007
                                         userInfo:@{NSLocalizedDescriptionKey:@"AVAssetExportSessionStatusNoPreset"}];
        [self movEncodeToMpegToolResult:nil error:error andResultBlock:resultBlock];
    }
}



+(NSDictionary *)getVideoInfo:(PHAsset *)asset {
    
    /// 包含该视频的基础信息
    PHAssetResource * resource = [[PHAssetResource assetResourcesForAsset: asset] firstObject];
    
    NSMutableArray *resourceArray = nil;
    
    if (@available(iOS 13.0, *)) {
        
        NSString *string1 = [resource.description stringByReplacingOccurrencesOfString:@" - " withString:@" "];
        
        NSString *string2 = [string1 stringByReplacingOccurrencesOfString:@": " withString:@"="];
        
        NSString *string3 = [string2 stringByReplacingOccurrencesOfString:@"{" withString:@""];
        
        NSString *string4 = [string3 stringByReplacingOccurrencesOfString:@"}" withString:@""];
        
        NSString *string5 = [string4 stringByReplacingOccurrencesOfString:@", " withString:@" "];
        
        resourceArray = [NSMutableArray arrayWithArray:[string5 componentsSeparatedByString:@" "]];
        
        [resourceArray removeObjectAtIndex:0];
        
        [resourceArray removeObjectAtIndex:0];
        
    } else {
        
        NSString *string1 = [resource.description stringByReplacingOccurrencesOfString:@"{" withString:@""];
        
        NSString *string2 = [string1 stringByReplacingOccurrencesOfString:@"}" withString:@""];
        
        NSString *string3 = [string2 stringByReplacingOccurrencesOfString:@", " withString:@","];
        
        resourceArray = [NSMutableArray arrayWithArray:[string3 componentsSeparatedByString:@" "]];
        
        [resourceArray removeObjectAtIndex:0];
        
        [resourceArray removeObjectAtIndex:0];
        
    }
    
    NSMutableDictionary *videoInfo = [[NSMutableDictionary alloc] init];
    
    for (NSString *string in resourceArray) {
        
        NSArray *array = [string componentsSeparatedByString:@"="];
        
        videoInfo[array[0]] = array[1];
        
    }
    
    videoInfo[@"duration"] = @(asset.duration).description;
    
    return videoInfo;
}


@end
